package Dm

import (
	"fmt"
	"db2s/ETL"
	"db2s/global"
	"db2s/parDef"
	"db2s/ref"
	"math"
)

func (sum SumF) Rows(parameter parDef.Parameter) (result global.Return, err error) {
	var event = "[DMRows]"
	var execSql []string
	for _, v := range []string{"all_tables", "dba_tables"} {
		execSql = append(execSql, fmt.Sprintf("select "+
			"num_rows as \"tableRows\" "+
			"from %v "+
			"where "+
			"owner='%s' and table_name='%s'",
			v, parameter.Object.Schema, parameter.Object.Table))
	}
	if result, err = forExecQuerySql(event, parameter, ETL.String, execSql); err != nil {
		err = ref.ErrAddPrintf("Rows", err)
		return
	}
	if result.Result, err = stringAnyToInt64(result.Result); err != nil {
		err = ref.ErrAddPrintf("Rows", err)
		return
	}
	return
}
func (sum SumF) Count(parameter parDef.Parameter) (result global.Return, err error) {
	//var event = "[DMCount]"
	var execSql []string
	execSql = append(execSql, fmt.Sprintf("select /*+ parallel(5) */ "+
		"count(1) as \"tableRows\" "+
		"from %v %v \n"+
		"where 1=1 %v %v %v",
		tableObject(parameter.Object.Schema, parameter.Object.Table, parameter.Object.Partition), specifyScn(parameter.Options.Scn),
		rowsLimitC(parameter.Options.RowsLimit), whereFilter(parameter.Options.WhereSql),
		//whereFilter(parameter.Options.WhereAdd)
		))
	//收集统计信息
	//if parameter.ExecSqlFunc != nil {
		//if result, err = parameter.ExecSqlFunc(modifyGetDbQueryOptions(parameter.GetDbQueryOptions(parameter), dataDispos.String), execSql); err != nil {
		//	err = ref.ErrAddPrintf(event, err)
		//	return
		//}
	//}
	if parameter.ExecFunc != nil {
		result.Result,err = parameter.ExecFunc(result.Result,nil)
	}
	return
}
func (sum SumF) Sum(parameter parDef.Parameter) (result global.Return, err error) {
	var sumValue int64
	if result, err = sum.Rows(parameter); err != nil {
		err = ref.ErrAddPrintf("Sum", err)
		return
	}
	if result.Result == nil {
		return
	}
	sumValue = result.Result.(int64)
	if sumValue > 1000000 {
		return
	}
	if result, err = sum.Count(parameter); err != nil {
		err = ref.ErrAddPrintf("Sum", err)
		return
	}
	return
}
func (sum SumF) DataSizeMB(parameter parDef.Parameter) (result global.Return, err error) {
	var execSql []string
	var event = "[DMDataSizeMB]"
	for _, v := range []string{"ALL_OBJECTS", "DBA_OBJECTS"} {
		execSql = append(execSql, fmt.Sprintf("SELECT\n\t\t"+
			"ROUND( SUM( bytes ) / 1048576, 2 ) AS \"dataSizeMB\" \n\t"+
			"FROM\n\t\t"+
			"DBA_SEGMENTS \n\t"+
			"WHERE\n\t\t"+
			"owner = '%v' \n\t\t"+
			"AND (\n\t\t\t"+
			"SEGMENT_NAME LIKE 'SYS_LOB' || "+
			"( SELECT "+
			"LPAD ( OBJECT_ID, 10, 0 ) "+
			"FROM %v "+
			"WHERE owner = '%v' "+
			"AND OBJECT_NAME = '%v' "+
			"AND object_type = 'TABLE' ) \n\t\t\t"+
			"OR segment_name = '%v') ", parameter.Object.Schema, v, parameter.Object.Schema, parameter.Object.Table, parameter.Object.Table))
	}
	if result, err = forExecQuerySql(event, parameter, ETL.String, execSql); err != nil {
		err = ref.ErrAddPrintf("DataSizeMB", err)
		return
	}
	if result.Result, err = stringAnyToFloat64(result.Result); err != nil {
		err = ref.ErrAddPrintf("DataSizeMB", err)
		return
	}
	return
}
func (sum SumF) IndexSizeMB(parameter parDef.Parameter) (result global.Return, err error) {
	var execSql []string
	var event = "[DMIndexSizeMB]"
	for _, v := range []string{"ALL_INDEXES", "DBA_INDEXES"} {
		execSql = append(execSql, fmt.Sprintf("SELECT\n\t\t"+
			"ROUND( SUM( bytes ) / 1048576, 2 ) AS \"indexSizeMB\" \n"+
			"\tFROM\n"+
			"\t\tDBA_SEGMENTS \n"+
			"\tWHERE\n\t\tOWNER = '%v' \n"+
			"\tAND SEGMENT_NAME IN "+
			"( "+
			"SELECT "+
			"INDEX_NAME "+
			"FROM %v "+
			"WHERE TABLE_OWNER = '%v' AND TABLE_NAME = '%v')",
			parameter.Object.Schema, v, parameter.Object.Schema, parameter.Object.Table))
	}
	if result, err = forExecQuerySql(event, parameter, ETL.String, execSql); err != nil {
		err = ref.ErrAddPrintf("IndexSizeMB", err)
		return
	}
	if result.Result, err = stringAnyToFloat64(result.Result); err != nil {
		err = ref.ErrAddPrintf("IndexSizeMB", err)
		return
	}
	return
}
func (sum SumF) DataLength(parameter parDef.Parameter) (result global.Return, err error) {
	var dataSize, indexSize float64
	if result, err = sum.DataSizeMB(parameter); err != nil {
		err = ref.ErrAddPrintf("DataLength", err)
		return
	}
	if result.Result == nil {
		return
	}
	dataSize = result.Result.(float64)
	if result, err = sum.IndexSizeMB(parameter); err != nil {
		err = ref.ErrAddPrintf("DataLength", err)
		return
	}
	if result.Result == nil {
		return
	}
	indexSize = result.Result.(float64)
	result.Result = math.Round((dataSize+indexSize)*100) / 100
	return
}
func (sum SumF) AvgRowsSize(parameter parDef.Parameter) (result global.Return, err error) {
	var execSql []string
	var event = "[AvgRowsSize]"
	execSql = append(execSql, fmt.Sprintf("select nvl(round(sum(avg_row_len)/count(1),0),0) AS \"AvgRowsSize\" from DBA_TAB_STATISTICS where owner = '%v' and table_name = '%v' group by table_name", parameter.Object.Schema, parameter.Object.Table))
	if result, err = forExecQuerySql(event, parameter, ETL.String, execSql); err != nil {
		err = ref.ErrAddPrintf("AvgRowsSize", err)
		return
	}
	if result.Result == nil {
		return
	}
	if result.Result, err = stringAnyToInt64(result.Result); err != nil {
		err = ref.ErrAddPrintf("AvgRowsSize", err)
		return
	}
	return
}
